package com.kmzx.one.project.service.impl;

import com.kmzx.one.common.exceptions.NoSuchObjectException;
import com.kmzx.one.common.utils.DateTimeUtils;
import com.kmzx.one.common.utils.UUIDGenerator;
import com.kmzx.one.project.config.wx.WxPayProperties;
import com.kmzx.one.project.entity.UserAuthentication;
import com.kmzx.one.project.entity.UserBankCert;
import com.kmzx.one.project.entity.UserCashDetail;
import com.kmzx.one.project.entity.UserCashFees;
import com.kmzx.one.project.entity.UserProfit;
import com.kmzx.one.project.entity.WxUser;
import com.kmzx.one.project.mapper.CustomerMapper;
import com.kmzx.one.project.mapper.UserAuthenticationMapper;
import com.kmzx.one.project.mapper.UserCashMapper;
import com.kmzx.one.project.mapper.UserProfitMapper;
import com.kmzx.one.project.mapper.WxUserMapper;
import com.kmzx.one.project.others.common.CashResult;
import com.kmzx.one.project.others.dto.UserProfitInfo;
import com.kmzx.one.project.service.UserCashService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class UserCashServiceImpl implements UserCashService {

    protected final Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    UserCashMapper userCashMapper;

    @Autowired
    WxUserMapper wxUserMapper;

    @Autowired
    WxPayProperties wxPayProperties;

    @Autowired
    UserAuthenticationMapper userAuthenticationMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private UserProfitMapper userProfitMapper;

    @Override
    public CashResult doWithdraw(String userId, BigDecimal money) {
        CashResult result = new CashResult();
        if (money != null && money.compareTo(BigDecimal.valueOf(100)) >= 0) {
            Date date = new Date();
            UserCashDetail detail = new UserCashDetail();
//            UserAuthentication info = getUserInfo(userId);
            UserBankCert info = getUserBankCert(userId);
            if (info == null) {
                throw new NoSuchObjectException(402, "暂未认证,提现申请失败");
            }
            detail.setId(UUIDGenerator.generate())
                    .setUserId(userId).setAppId(wxPayProperties.getAppId())
                    .setApplyMoney(money).setApplyTime(date)
                    .setOpenId(getOpenId(userId)).setKinds(0).setCanRead(0)
                    .setStates(0).setIdCard(info.getIdCard()).setIdCardName(info.getUsername());
            detail.setCardBefore(info.getIdCardFront()).setCardAfter(info.getIdCardBack());
            detail.setUserPhone(info.getPhone()).setBankCard(info.getBankCard());
//            detail.setSettlementMoney(toComputeFee(userId, money));
            detail.setSettlementMoney(money);
            detail.setUserCashCodes(UUIDGenerator.generateOrderNo("TX"));
            UserProfitInfo dto = customerMapper.selectUserProfit(userId);

            if (dto.getCanPay().compareTo(money) >= 0) {
                BigDecimal endMoney = dto.getCanPay().subtract(money);
                UserProfit profit = new UserProfit();
                profit.setProfitMoney(endMoney);
                profit.setUpdateTime(date);
                profit.setId(dto.getTemps());
                userProfitMapper.updateByIdSelective(profit);
                logger.info("提现扣除账户表成功");
                userCashMapper.insertUserCashDetail(detail);
                logger.info("提现表记录插入成功");
                result.setSuccess(true).setCashId(detail.getId()).setReason(null);
            } else {
                result.setSuccess(false).setReason("可提现余额不足");
                return result;
            }
        }
        return result;
    }

    public String getOpenId(String userId) {
        WxUser user = wxUserMapper.selectById(userId);
        if (user != null) {
            return user.getOpenId();
        }
        return null;
    }

    public UserAuthentication getUserInfo(String userId) {
        UserAuthentication authentication = userAuthenticationMapper.selectByUserId(userId);
        return authentication;
    }

    public UserBankCert getUserBankCert(String userId) {
        List<UserBankCert> infos = customerMapper.selectUserBankCert(userId);
        if (infos != null && infos.size() > 0) {
            return infos.get(0);
        } else {
            throw new NoSuchObjectException(402, "暂未认证,提现申请失败");
        }
    }

    public BigDecimal toComputeFee(String userId, BigDecimal money) {
        Date monthFirstDay = DateTimeUtils.getMonthFirstDay();
        Date today = new Date();
        List<UserCashFees> fees = userCashMapper.selectAllUserCashFees();
        BigDecimal everMoney = userCashMapper.selectMyWithdrawMonth(userId, monthFirstDay, today);
        if (everMoney != null) {
//            UserCashFees cashFees = fees.stream().filter(mm -> mm.getCashEnd().compareTo(everMoney) > 0 && mm.getCashStart().compareTo(everMoney) < 0).findAny().get();
//            BigDecimal oldRate = cashFees.getChargeRate();
//            BigDecimal everFeeMoney = everMoney.multiply(oldRate);
//
//
//            BigDecimal cashEnd = cashFees.getCashEnd();
//            BigDecimal add = money.add(everMoney);
//            if (add.compareTo(cashEnd) < 0) {
//                BigDecimal rate = cashFees.getChargeRate();
//                BigDecimal endMoney = money.subtract(cashFees.getSubtractMoney());
//                BigDecimal endFee = endMoney.multiply(rate);
//                return endFee;
//            } else {
//
//            }
            throw new NoSuchObjectException(402, "本月已经申请过提现");
        } else {
            //  没有提现过
            UserCashFees cashFees = fees.stream().filter(mm -> mm.getCashEnd().compareTo(money) > 0 && mm.getCashStart().compareTo(money) < 0).findAny().get();
            BigDecimal rate = cashFees.getChargeRate();
            BigDecimal endMoney = money.subtract(cashFees.getSubtractMoney());
            BigDecimal endFee = endMoney.multiply(rate);
            BigDecimal allMoney = money;
            BigDecimal subtract = allMoney.subtract(endFee);
            return subtract;
        }
    }

    @Override
    public int cancelWithdraw(String userId, String cashId) throws Exception {

        UserProfitInfo dto = customerMapper.selectUserProfit(userId);
        UserCashDetail end = userCashMapper.selectKey(cashId);
        if (end != null && dto != null) {
            Integer states = end.getStates();
            if (states == 0 || states == 7) {


                BigDecimal canPay = dto.getCanPay();

                String profitId = dto.getTemps();
                BigDecimal applyMoney = end.getApplyMoney();

                UserProfit profit = new UserProfit();
                profit.setId(profitId);
                profit.setProfitMoney(canPay.add(applyMoney));
                profit.setUpdateTime(new Date());

                UserCashDetail detail = new UserCashDetail();
                detail.setId(cashId).setDoneTime(new Date()).setStates(7);


                userProfitMapper.updateByIdSelective(profit);
                logger.info("提现撤销表成功");
                userCashMapper.updateByIdSelect(detail);

            } else {
                throw new NoSuchObjectException(402, "提现订单已在处理中,取消失败!");
            }

        } else {
            if (dto == null) {
                throw new NoSuchObjectException(402, "账户不存在");
            }
            if (end == null) {
                throw new NoSuchObjectException(402, "提现记录不存在");
            }
        }

        return 0;
    }
}
